from datetime import datetime

from django.forms import model_to_dict
from comment.errorcode import *
from .models import *
import logging
from comment.errorcode import *


# error
def error_ret(error, message):
    return [error, message, None]


def paging(data_list, page, size):
    """
    分页
    :param data_list:数据列表
    :param page:页数
    :param size:页长度
    :return:
    """
    size = int(size)
    page = int(page)
    ret = {
        'page': page, 'size': size, 'total_page': 0, 'total_size': 0
    }
    total_size = data_list.count()
    if total_size % size == 0:
        total_page = total_size / size
    else:
        total_page = total_size / size + 1
    start_index = (page - 1) * size
    end_index = page * size
    
    ret['total_page'] = total_page
    ret['total_size'] = total_size
    if end_index > len(data_list):
        ret['result'] = data_list[start_index:]
        ret["end"] = False
    else:
        ret["end"] = True
        ret['result'] = data_list[start_index: end_index]
    return ret


# demo
# 增
def demo_add(**kwargs):
    title = kwargs.get("title")
    last_update = create_time = datetime.now()
    remarks = kwargs.get("remarks")
    download_time = 0
    read_time = 0
    clock = 0
    supreme = 0
    collect_time = 0
    content = kwargs.get("content")
    author_id = kwargs.get("author_id")
    classes_id = kwargs.get("classes_id")
    scene_id = kwargs.get("scene_id")
    product = kwargs.get("product")
    try:
        author = User.objects.get(id=author_id)
        classes = DemoClasses.objects.get(id=classes_id)
        scene = Scene.objects.get(id=scene_id)
    except Exception as e:
        logging.error(e)
        return ErrorMsg(SELECT_ERROR, "参数有误")
    
    try:
        result = Demo.objects.create(
            title=title, last_update=last_update, creat_time=create_time,
            remarks=remarks, content=content, download_time=download_time,
            read_time=read_time, clock=clock, supreme=supreme, product=product,
            author=author, classes=classes, scene=scene, collect_time=collect_time
        )
        return result
    except Exception as e:
        logging.error(e)
        return ErrorMsg(CREATE_ERROR, "参数有误")


# 删
def demo_del(id):
    try:
        demo = Demo.objects.get(id=id)
    except Exception as e:
        logging.error("查询失败[demo_del]")
        return False
    if len(demo) == 0:
        logging.error("查询失败[demo_del]")
        return False
    try:
        result = demo.delete()
        return False
    except Exception as e:
        logging.error("删除失败[demo_del]")
        return True


# 改
def demo_update(id, **kwargs):
    try:
        demo = Demo.objects.get(id=id)
    except Exception as e:
        logging.error(e)
        return ErrorMsg(SERVER_EMPTY)
    title = kwargs.get("title")
    last_update = datetime.now()
    remarks = kwargs.get("remarks")
    clock = 0
    content = kwargs.get("content")
    author_id = kwargs.get("author_id")
    classes_id = kwargs.get("classes_id")
    scene_id = kwargs.get("scene_id")
    product = kwargs.get("product")
    try:
        author = User.objects.get(id=author_id)
        classes = DemoClasses.objects.get(id=classes_id)
        scene = Scene.objects.get(id=scene_id)
    except Exception as e:
        logging.error(e)
        return ErrorMsg(SELECT_ERROR, "参数有误")
    
    try:
        result = Demo.objects.filter(id=id).update(
            title=title, last_update=last_update,
            remarks=remarks, content=content, clock=clock,
            author=author, classes=classes, scene=scene, product=product
        )
        return demo
    except Exception as e:
        logging.error(e)
        return ErrorMsg(UPDATE_ERROR, "参数有误")


def demo_superme(demo_id):
    try:
        demo = Demo.objects.get(id=demo_id)
    except Exception as e:
        logging.error(e)
        return ErrorMsg(SELECT_ERROR, "获取案例失败")
    if demo is None:
        return ErrorMsg(SELECT_ERROR,"获取案例失败")
    try:
        demo.supreme = 0 if demo.supreme else 1
        demo.save()
        return demo.supreme
    except Exception as e:
        return ErrorMsg(SELECT_ERROR,"获取案例失败")


def demo_read_add(id):
    try:
        demo = Demo.objects.get(id=id)
    except Exception as e:
        logging.error("查询失败[demo_update]", e)
        return False
    if demo is None:
        logging.error("查询失败[demo_update]")
        return False
    try:
        # read_time = demo.read_time + 1
        demo.read_time = demo.read_time + 1
        demo.save()
        # demo.objects.update(read_time=read_time)
        return True
    except Exception as e:
        logging.error("更新失败[demo_update]", e)
        return False


def demo_collect_update(demo_id, delete):
    try:
        demo = Demo.objects.get(id=demo_id)
    except Exception as e:
        logging.error("查询失败[demo_update]")
        return False
    if demo is None:
        logging.error("查询失败[demo_update]")
        return False
    try:
        if delete:
            demo.collect_time = demo.collect_time - 1 if demo.collect_time > 0 else 0
        else:
            demo.collect_time = demo.collect_time + 1
        demo.save()
        return True
    except Exception as e:
        logging.error("更新失败[demo_update]")
        return False


# 查
def demo_reslizer(result, func_title):
    for demo_dict in result:
        try:
            demo_dict["author"] = User.objects.get(id=demo_dict.get("author")).name if demo_dict.get("author") else None
            demo_dict["classes"] = DemoClasses.objects.get(id=demo_dict.get("classes")).title if demo_dict.get(
                "classes") else None
            demo_dict["scene"] = Scene.objects.get(id=demo_dict.get("scene")) if demo_dict.get("scene") else None
        except Exception as e:
            logging.error("序列化失败:[{}]{}".format(func_title, e))
    return result


def demo_list():
    demos = Demo.objects.all()
    if len(demos) == 0:
        logging.error("查询失败[demo_list]")
        return None
    try:
        result = [model_to_dict(demo) for demo in demos]
        result = demo_reslizer(result, "demo_list")
        return result
    except:
        return None


def demo_list_classes(cls_id, size, page, supreme=False):
    """
    通过分类获得demo
    :param request:
    :return:
    """
    demos = None
    try:
        democls = DemoClasses.objects.get(id=cls_id)
        if democls is None:
            return None
        if supreme:
            demos = Demo.objects.filter(classes=democls, supreme=True).values("id", "title")
        else:
            demos = Demo.objects.filter(classes=democls).values("id", "title")
    except Exception as e:
        return None
    if demos is None:
        logging.error("查询失败[demo_list_classes]：{}".format(democls))
        return None
    try:
        demos = paging(demos, page, size)
        # result = [model_to_dict(demo) for demo in demos]
        # result = demo_reslizer(result, "demo_list_classes")
        return demos
    except:
        return None


def demo_list_author(author_id, size, page):
    try:
        author = User.objects.get(id=author_id)
        demos = Demo.objects.filter(author=author).extra({'demo_id': 'id'}).values("id", "title", "creat_time", "clock",
                                                                                   "supreme")
    except Exception as e:
        logging.error(e)
        return ErrorMsg(SELECT_ERROR, "")
    if len(demos) == 0:
        logging.error("查询失败[demo_list_author]：{}".format(author))
        return None
    try:
        demos = paging(demos, page, size)
        # result = list(demos)
        # result = demo_reslizer(result, "demo_list_author")
        return demos
    except Exception as e:
        logging.error(e)
        return ErrorMsg(SELECT_FORMAT_ERR, "序列化失败")


def demo_list_scene(classes_id, scene, size, page, supreme=False):
    try:
        classes = DemoClasses.objects.get(id=classes_id)
        if supreme:
            demos = Demo.objects.filter(classes=classes, scene=scene, supreme=True).values()
        else:
            demos = Demo.objects.filter(classes=classes, scene=scene).values()
    except Exception as e:
        logging.error(e)
        return ErrorMsg(SELECT_ERROR, "")
    if len(demos) == 0:
        logging.error("查询失败[demo_list_author]：{}".format(classes))
        return []
    try:
        demos = paging(demos, size, page)
        # result = [model_to_dict(demo) for demo in demos.get("data")]
        # result = demo_reslizer(result, "demo_list_author")
        return demos
    except Exception as e:
        logging.error(e)
        return ErrorMsg(SELECT_FORMAT_ERR, "序列化失败")


def demo_info(demo_id, params=None, get_all=True):
    try:
        if get_all:
            demo = Demo.objects.select_related().filter(id=demo_id).values()
        else:
            demo = Demo.objects.select_related().filter(id=demo_id).values(*params)
    except Exception as e:
        return ErrorMsg(SELECT_ERROR, "文档查询失败")
    if demo.count() == 0:
        logging.error("查询失败[demo_info]：{}".format(demo_id))
        return ErrorMsg(SELECT_ERROR, "文档查询失败")
    try:
        result = list(demo)[0]
        # result = demo_reslizer(result, "demo_info")
        return result
    except:
        return ErrorMsg(SELECT_ERROR, "文档查询失败")


def demo_top10():
    try:
        result = list(Demo.objects.all().order_by("creat_time", "read_time").values("title", "id"))
    except Exception as e:
        logging.error(e)
        return None
    if len(result) > 10:
        for value in result[0:10]:
            value["url"] = "/demomanager/demo?active=read"
        return result[0:10]
    else:
        for value in result:
            value["url"] = "/demomanager/demo?active=read"
        return result


# content
# 增
# 删
# 改
# 查

# product
# 增
# 删
# 改
# 查

# fault
# 增
# 删
# 改
# 查

# scene
# 增
# 删
# 改
# 查

# demofile
# 增
# 删
# 改
# 查
def demofile_list_demo(demo_id):
    try:
        result = DemoFile.objects.filter(demo_id=demo_id).values("title", "files")
        return result
    except Exception as e:
        return None


# democlasses
# 增
# 删
# 改
# 查
def democlasses_list(get_parent=True, get_child=True, get_url=True):
    result = []
    if get_parent:
        result = list(DemoClasses.objects.filter(parent_id__isnull=True).values())
    if get_child and get_parent:
        parents = DemoClasses.objects.filter(parent_id__isnull=True)
        for parent in parents:
            data = {}
            data["parent"] = {"menu_name": parent.title}
            childs = list(DemoClasses.objects.filter(parent_id=parent).values("id", "title"))
            child_list = []
            for child in childs:
                child["second_menu_name"] = child.get("title")
                if get_url:
                    child["second_menu_url"] = "/demomanager/demo?active=main"
                child["second_menu_id"] = child.get("id")
                child_list.append(child)
            data["childs"] = child_list
            if len(child_list) != 0:
                data["parent"]["menu_url"] = data["childs"][0]["second_menu_url"]
            result.append(data)
    elif get_child:
        result = list(DemoClasses.objects.filter(parent_id__isnull=False).values())
    return result


# collect
# 增
# 删
# 改
# 查
def collect_info_user(user_id, demo_id):
    try:
        num = Collect.objects.filter(user_id=user_id, demo_id=demo_id).count()
        if num:
            return True
        return False
    except Exception as e:
        return False


def scene_list(get_urls=True):
    try:
        scene = list(Scene.objects.all().values("name", "id"))
        if get_urls:
            for value in scene:
                value["url"] = "/demomanager/demo?active=main"
        return scene
    except Exception as e:
        logging.error(e)
        return None


def indexchar_add(args, demo):
    indexchar = []
    if args is None:
        return None
    for arg in args:
        try:
            if IndexChar.objects.filter(name=arg, demo=demo).exists():
                indexchar.append(arg)
                continue
            else:
                IndexChar.objects.create(name=arg, demo=demo)
            indexchar.append(arg)
        except Exception as e:
            logging.error(e)
            return ErrorMsg(CREATE_ERROR)
    return indexchar


def indexchar_list(demo_id):
    try:
        demo = Demo.objects.get(id=demo_id)
    except Exception as e:
        logging.error(e)
        return ErrorMsg(SELECT_ERROR)
    indexchar = IndexChar.objects.filter(demo=demo).values("name")
    return list(indexchar)


def demofile_add(file):
    try:
        result = DemoFile.objects.create(files=file)
        return result
    except Exception as e:
        logging.error(e)
        return ErrorMsg(CREATE_ERROR)


def files_list_demo(demo):
    try:
        files = DemoFile.objects.filter(demo_id=demo)
    except Exception as e:
        logging.error(e)
        return ErrorMsg(FILE_SELECT_ERR)
    return files


def files_bind_demo(demo, files_id):
    """
    文件文件和demo绑定
    :param demo:
    :param files_id:
    :return:
    """
    if files_id is None:
        return None
    for file_id in files_id:
        try:
            demo_file = DemoFile.objects.get(id=file_id)
            result = demo_file.objects.update(demo_id=demo)
        except Exception as e:
            logging.error(e)
            return ErrorMsg(FILE_UPDATE_ERR)
    return None


def files_unbind_demo(demo, files_id):
    """
    文件文件和demo解绑
    :param demo:
    :param files_id:
    :return:
    """
    if files_id is None:
        return None
    for file_id in files_id:
        try:
            demo_file = DemoFile.objects.get(id=file_id)
            result = demo_file.delete()
        except Exception as e:
            logging.error(e)
            return ErrorMsg(FILE_UPDATE_ERR)
    return None


def collect_add(demo_id, user_id):
    try:
        user = User.objects.get(id=user_id)
        demo = Demo.objects.get(id=demo_id)
    except Exception as e:
        logging.error(e)
        return ErrorMsg(SELECT_ERROR, "文件或用户查询不到")
    try:
        if Collect.objects.filter(user_id=user, demo_id=demo).count() > 0:
            return ErrorMsg(CREATE_ERROR, "不能收藏两次")
        result = Collect.objects.create(user_id=user, demo_id=demo)
        return result
    except Exception as e:
        logging.error(e)
        return ErrorMsg(CREATE_ERROR, "收藏失败")


def collect_del(demo_id, user_id):
    try:
        user = User.objects.get(id=user_id)
        demo = DemoFile.objects.get(id=demo_id)
    except Exception as e:
        logging.error(e)
        return ErrorMsg(SELECT_ERROR, "文件或用户查询不到")
    try:
        collect = Collect.objects.filter(user_id=user, demo_id=demo)
        result = collect.delete()
        return result
    except Exception as e:
        logging.error(e)
        return ErrorMsg(CREATE_ERROR, "收藏失败")


def collect_list(user_id, page, size):
    try:
        user = User.objects.get(id=user_id)
    except Exception as e:
        logging.error(e)
        return ErrorMsg(SELECT_ERROR, "用户查询不到")
    try:
        collects = Collect.objects.filter(user_id=user).values("id", "title")
        result = paging(collects, page, size)
        return result
    except Exception as e:
        logging.error(e)
        return ErrorMsg(CREATE_ERROR, "收藏失败")
